export const getInputFieldFC = (path: string, fieldName: string, gqlFieldType: string): string => {

    if (gqlFieldType === "String")
        return `
    <Form.Item label="${fieldName}">
        <Input
            value={inputParameters.${path}.${fieldName}!}
            onChange={e => {
                const i = { ...inputParameters }
                i.${path}.${fieldName} = e.target.value
                setInputParameters(i)
            }}
        />
    </Form.Item>
`

    if (gqlFieldType === "Int")
        return `
    <Form.Item label="${fieldName}">
        <InputNumber
            value={inputParameters.${path}.${fieldName}!}
                onChange={value => {
                const i = { ...inputParameters }
                i.${path}.${fieldName} = value
                setInputParameters(i)
            }}
        />
    </Form.Item>
`


    if (gqlFieldType === "Boolean")
        return `
    <Form.Item label="${fieldName}">
        <Checkbox
            checked={inputParameters.${path}.${fieldName}!}
            onChange={e => {
                const i = { ...inputParameters }
                i.${path}.${fieldName} = e.target.checked
                setInputParameters(i)
            }}
        />
    </Form.Item>

`

    if (gqlFieldType === "BigDecimal")
        return `
    <Form.Item label="${fieldName}">
        <InputNumber
            value={inputParameters.${path}.${fieldName}!}
            
            onChange={value => {
                const i = { ...inputParameters }
                i.${path}.${fieldName} = value
                setInputParameters(i)
            }}
        />
    </Form.Item>
`

    if (gqlFieldType === "_Date")
        return `
    <Form.Item label="${fieldName}">
        <DatePicker
            value={inputParameters.${path}.${fieldName} ? moment(inputParameters.${path}.${fieldName}, "YYYY-MM-DD") : null}
            onChange={moment => {
                const i = { ...inputParameters }
                i.${path}.${fieldName} = moment?.format("YYYY-MM-DD")
                setInputParameters(i)
            }}
            format="YYYY-MM-DD"
        />
    </Form.Item>

`
    if (gqlFieldType === "_DateTime")
        return `
            <Form.Item label="${fieldName}">
                <DatePicker
                    showTime={{ format: 'HH:mm:ss' }}
                    value={inputParameters.${path}.${fieldName} ? moment(inputParameters.${path}.${fieldName}.replace("T", " "), "YYYY-MM-DD HH:mm:ss") : null}
                    onChange={moment => {
                        const i = { ...inputParameters }
                        i.${path}.${fieldName} = moment?.format("YYYY-MM-DD HH:mm:ss").replace(" ", "T")
                        setInputParameters(i)
                    }}
                    format="YYYY-MM-DD HH:mm:ss"
                />
            </Form.Item>
`


    return ""
}

export const getEntityListFC = (
    entityName: string,
    inputFieldFCList: string,
    listColumns: string,
    elemToColumnMapString: string,
    columnToInputMapString: string
): string => {

    const EntityName = entityName.charAt(0).toUpperCase() + entityName.slice(1);
    return `
import React, { FC, useEffect, useState } from 'react';

import { Button, Col, Checkbox, DatePicker, Form, Input, InputNumber, Modal, Row, Spin, Table } from 'antd';

import {
    Search${EntityName}Document,
    _Create${EntityName}Input, 
    useCreate${EntityName}Mutation, 
    useDelete${EntityName}Mutation, 
    useSearch${EntityName}Query, 
    _Update${EntityName}Input, 
    ${EntityName}SearchAttributesFragment, 
    useUpdate${EntityName}Mutation, 
    Update${EntityName}MutationVariables,
    Create${EntityName}MutationVariables
} from '../../__generate/graphql-frontend'

import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons';
import ErrorModal from '../basic/ErrorModal';
import Search from 'antd/lib/input/Search';
import moment from 'moment';



enum ShowForm {
    None,
    Create,
    Update
}


function mapViewToInput(data: ${EntityName}SearchAttributesFragment): Update${EntityName}MutationVariables {
    return {
        input: {
            id: data.id,
            ${columnToInputMapString}
        }
    }
}

export const ${EntityName}List: FC = () => {

    const columns = ${listColumns}

    const [deleteId, setDeleteId] = useState<string | null>(null)
    const [showForm, setShowForm] = useState<ShowForm>(ShowForm.None)
    const [error, setError] = useState<Error | null>(null)

    const [inputParameters, setInputParameters] = useState<Update${EntityName}MutationVariables | Create${EntityName}MutationVariables>()


    const [searchStr, setSearchStr] = useState<string>("")


    const { data, loading, error: errorQuery } = useSearch${EntityName}Query({
        variables: {
            searchStr
        }
    })
    const ${entityName}List = data?.search${EntityName}.elems

    const [create${EntityName}Mutation, { error: errorCreate, data: dataCreate }] = useCreate${EntityName}Mutation()
    const [update${EntityName}Mutation, { error: errorUpdate, data: dataUpdate }] = useUpdate${EntityName}Mutation()
    const [delete${EntityName}Mutation, { error: errorDelete }] = useDelete${EntityName}Mutation()



    useEffect(() => {
        const err = [errorQuery, errorCreate, errorUpdate, errorDelete].find(e => e)
        if (err) {
            setError(err)
        }

    }, [errorQuery, errorCreate, errorUpdate, errorDelete])

    useEffect(() => {
        if (dataCreate || dataUpdate)
            setShowForm(ShowForm.None)
    },
        [dataCreate, dataUpdate]
    )

    const mapToView = (list: Array<${EntityName}SearchAttributesFragment>) => {
        return (
            list?.map(elem => {
                return {
                    key: elem.id ?? "",
                    id: elem.id,
                    ${elemToColumnMapString}
                    actions: <>
                        <Button style={{ margin: "5px" }}
                            key={"e" + elem.id}
                            onClick={() => {
                                setInputParameters(mapViewToInput(elem))
                                setShowForm(ShowForm.Update)
                            }}
                        ><EditOutlined />
                        </Button>
                        <Button style={{ margin: "5px" }}
                            key={"d" + elem.id}
                            onClick={() => { setDeleteId(elem.id) }}
                        ><DeleteOutlined /></Button>
                    </>
                }
            })
        )
    }

    if (loading) return (<Spin tip="Loading..." />);
    if (error) return (<ErrorModal error={error} setError={setError} />)

    return (
        <>
            <Modal visible={deleteId != null}
                onCancel={() => setDeleteId(null)}
                onOk={
                    () => {
                        delete${EntityName}Mutation({
                            variables: {
                                id: deleteId!
                            },
                            update: (store) => {
                                store.writeQuery({
                                    query: Search${EntityName}Document,
                                    variables: { searchStr },
                                    data: {
                                        search${EntityName}: {
                                            elems: ${entityName}List!.filter(x => x.id !== deleteId)
                                        }
                                    }
                                })
                            }
                        })
                        setDeleteId(null)
                    }
                }
            >Delete?</Modal>
            <Row style={{ margin: "5px" }}>
                <Col span="4">
                    <Button
                        onClick={() => {
                            setInputParameters({ input: {} })
                            setShowForm(ShowForm.Create)
                        }}>
                        <PlusOutlined></PlusOutlined>
                    </Button>
                </Col>
                <Col span="4">
                    <Search defaultValue={searchStr} onSearch={(value) => setSearchStr(value)} />
                </Col>
            </Row>

            <Modal visible={showForm != ShowForm.None}
                onCancel={() => setShowForm(ShowForm.None)}
                onOk={() => {
                    if (showForm == ShowForm.Create) {
                        create${EntityName}Mutation({
                            variables: inputParameters as Create${EntityName}MutationVariables,
                            update: (store, result) => {
                                store.writeQuery({
                                    query: Search${EntityName}Document,
                                    variables: { searchStr },
                                    data: {
                                        search${EntityName}: {
                                            elems: [, ...${entityName}List!, result.data?.packet?.create${EntityName}]
                                        }
                                    }
                                })
                            }
                        })
                    } else if (showForm == ShowForm.Update) {
                        update${EntityName}Mutation({ variables: inputParameters as Update${EntityName}MutationVariables })
                    }
                }}
            >
                {inputParameters &&
                    <${EntityName}Edit
                        inputParameters={inputParameters}
                        setInputParameters={setInputParameters}
                    />
                }

            </Modal>
            {${entityName}List &&
                <Table
                    columns={columns}
                    dataSource={mapToView(${entityName}List)}
                />}

        </>
    )
}

type InputParameters = {
    inputParameters: Update${EntityName}MutationVariables | Create${EntityName}MutationVariables,
    setInputParameters: (input: Update${EntityName}MutationVariables | Create${EntityName}MutationVariables) => void
}

const ${EntityName}Edit: FC<InputParameters> = ({ inputParameters, setInputParameters }) => {

    return (
        <Form>
            ${inputFieldFCList}
        </Form>
    )
}
`
}